package com.hichina.client.util;

import com.hichina.exception.HiChinaException;
import com.hichina.exception.InvalidTokenException;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import org.apache.log4j.Logger;

import java.io.IOException;

/**
 * Created by IntelliJ IDEA.
 * User: zigang.wang
 * Date: 12-2-29
 * Time: 上午9:19
 * To change this template use File | Settings | File Templates.
 */
public class HttpClientUtils {
    public static final Logger log = Logger.getLogger(HttpClientUtils.class);
    private String accessToken;
    public final String redirectURI;
    public final String client_id;
    public final String client_secret;
    private String apiServer;

    public HttpClientUtils(String accessToken, String redirectURI, String client_id, String client_secret, String apiServer) {
        this.accessToken = accessToken;
        this.redirectURI = redirectURI;
        this.client_id = client_id;
        this.client_secret = client_secret;
        this.apiServer = apiServer;
    }

    public HttpClientUtils() {
        this.redirectURI = Setting.getSetting("redirect_uri");
        this.client_id = Setting.getSetting("client_key");
        this.client_secret = Setting.getSetting("client_secret");
        this.apiServer = Setting.getSetting("baseURI");
    }

    public String getApiServer() {
        return apiServer;
    }

    public void setApiServer(String apiServer) {
        this.apiServer = apiServer;
    }

    public String get(String url) throws InvalidTokenException, HiChinaException {
        try {
            String content = get(url, "utf-8");
            log.info("request..." + url + "\n response : " + content);
            return content;
        } catch (IOException e) {
            log.error("getToken error:", e);
            throw new HiChinaException("connect exception");
        }
    }

    public String get(String url, String encoding) throws IOException, InvalidTokenException {
        url = StringUtils.replace(url, " ", "%20");
        HttpGet httpGet = new HttpGet(url);
        DefaultHttpClient httpClient = new DefaultHttpClient();
        HttpResponse res = httpClient.execute(httpGet);
        return getContent(res, encoding);
    }


    public String getContent(HttpResponse res, String encoding) throws IOException, InvalidTokenException {
        HttpEntity ent = res.getEntity();
        String result = IOUtils.toString(ent.getContent(), encoding);
//        ent.consumeContent();
        EntityUtils.consume(ent);
        if (StringUtils.contains(result, "\"error\": \"invalid_token\"")) {
            throw new InvalidTokenException("Invalid access token, please refresh accessToken");
        } else if (StringUtils.contains(result, "\"error\":")) {
            throw new InvalidTokenException(result);
        }
        return result;
    }

    public void setAccessToken(String accessToken) {
        this.accessToken = accessToken;
    }

    /**
     * 获取AccessToken
     *
     * @param code
     * @return
     * @throws HiChinaException
     */
    public String getAccessToken(String code) throws HiChinaException, InvalidTokenException {
        HttpParam param = new HttpParam();
        param.setClientId(client_id);
        param.setClientSecret(client_secret);
        param.setRedirectUri(redirectURI);
        param.setGrantType("authorization_code");
        param.setParameter("code", code);
        return get(getApiServer() + "/oauth/token?" + param.toString());

    }

    public String refreshAccessToken(String refreshToken) throws HiChinaException, InvalidTokenException {
        HttpParam param = new HttpParam();
        param.setClientId(client_id);
        param.setClientSecret(client_secret);
        param.setRedirectUri(redirectURI);
        param.setGrantType("refresh_token");
        param.setScope("read write");
        param.setParameter("refresh_token", refreshToken);
        return get(getApiServer() + "/oauth/token?" + param.toString());

    }

    /**
     * 获取当前登录用户email
     *
     * @return
     * @throws HiChinaException
     * @throws InvalidTokenException
     */
    public String getUid() throws HiChinaException, InvalidTokenException {
        return get(getApiServer() + "/api/account/get_uid?" + new HttpParam(accessToken));

    }

    public String getAccountStatus(String uid) throws InvalidTokenException, HiChinaException {
        return get(getApiServer() + "/api/account/status?" + new HttpParam(accessToken).setUid(uid));
    }

    /**
     * 获取用户email详情
     *
     * @param uid
     * @return
     * @throws InvalidTokenException
     * @throws IOException
     */
    public String getAccountInfo(String uid) throws InvalidTokenException, HiChinaException {
        return get(getApiServer() + "/api/account/show?" + new HttpParam(accessToken).setUid(uid));

    }

    public String getContactList(String uid, int offset, int length) throws HiChinaException, InvalidTokenException {
        return get(getApiServer() + "/api/domain/accounts?offset=" + offset + "&length=" + length + "&" + new HttpParam(accessToken).setUid(uid));
    }

    public String getValidList(String uid) throws HiChinaException, InvalidTokenException {
        return get(getApiServer() + "/api/domain/valid_accounts?" + new HttpParam(accessToken).setUid(uid));
    }

    public String getDomainInfo(String uid) throws HiChinaException, InvalidTokenException {
        return get(getApiServer() + "/api/domain/show?" + new HttpParam(accessToken).setUid(uid));
    }

    public String getMail(String uid) throws HiChinaException, InvalidTokenException {
        return get(getApiServer() + "/api/account/uid2mail?" + new HttpParam(accessToken).setUid(uid));
    }

    public String listDepartment(String domain) throws HiChinaException, InvalidTokenException {
        return get(getApiServer() + "/api/department?" + new HttpParam(accessToken).setDomain(domain));
    }

    public String listDepartmentAccount(String domain, String departmentId, int offset, int length) throws HiChinaException, InvalidTokenException {
        return get(getApiServer() + "/api/department/account?offset=" + offset + "&length=" + length + "&" 
                + new HttpParam(accessToken).setDomain(domain).setParameter("department_id", departmentId));
    }

    public String listAccounts(String domain, int offset, int length, long fecthtime) throws HiChinaException, InvalidTokenException {
        return get(getApiServer() + "/api/organizer?offset=" + offset + "&length=" + length + "&" +
        new HttpParam(accessToken).setDomain(domain).setParameter("lastfetchtime", fecthtime));
    } 
}
